package org.jslaughter.camera.plugin;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.geom.Vector2f;

import org.nvframe.camera.Camera;
import org.nvframe.camera.plugin.CameraPlugin;
import org.nvframe.component.state.Position;
import org.nvframe.entity.Entity;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.UpdateEvent;
import org.nvframe.event.eventtype.UpdateListener;

public class SmoothFollowPlugin implements CameraPlugin, UpdateListener {
	
	private Camera camera;
	private Entity focusEntity;
	
	private float latency = 20f;
	private Vector2f velocity = new Vector2f();
	private int minDiff = 0;
	
	public SmoothFollowPlugin(Entity focusEntity) {
		this.focusEntity = focusEntity;
		
		EventService.getInstance().addEventListener(this);
	}
	
	public void setCamera(Camera camera) {
		this.camera = camera;
	}
	
	@Override
	public void onUpdate(UpdateEvent event) {		
		Position entityPosition = (Position) focusEntity.getComponent(Position.class);
		
		if(entityPosition == null)
			return;
		
		GameContainer gc = event.getGc();
		int delta = event.getDelta();
		
		Vector2f cameraPos = camera.getPosition();
		cameraPos.x += gc.getWidth() / 2;
		cameraPos.y += gc.getHeight() / 2;
		Vector2f diff = entityPosition.getXY().sub(cameraPos);
		
		float cameraAX = (2 * (diff.x - velocity.x * latency)) / (latency * latency);
		float cameraAY = (2 * (diff.y - velocity.y * latency)) / (latency * latency);
		
		if(minDiff != 0 && Math.abs(diff.x) <= minDiff) {
			velocity.x = 0;
			cameraAX = 0;
		}
		if(minDiff != 0 && Math.abs(diff.y) <= minDiff) {
			velocity.y = 0;
			cameraAY = 0;
		}

		velocity.x += cameraAX * delta;
		velocity.y += cameraAY * delta;

		cameraPos.x += velocity.x * delta - (gc.getWidth() / 2);
		cameraPos.y += velocity.y * delta - (gc.getHeight() / 2);
		
		camera.setPosition(cameraPos);
		
	}
	
}
